/**
 * File: ControllerGeneric.java
 * Data: 03.10.2010
 * Objective: Criar um controller generico para todos controllers do projecto.
 *
 * Copyright 2010 S2DZ CORPORATION

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package controller;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import util.ConnecctionBD;

/**
 * @author Paulo Ilenga
 * Define a extrutura de um controller generico que será a superclasse de todos
 * os controllers do projecto.
 */
public abstract class ControllerGeneric extends ConnecctionBD implements ControllerInterface, Serializable
{
    protected ResultSet rs;
    protected PreparedStatement ps;
    protected String sql;
    protected boolean result;

    public ControllerGeneric()
    {
        connect();
    }

    /**
     * Remove um registo da base de dados.
     * @param id chave do registo.
     * @param table nome da tabela na base de dados.
     * @return o resusltado da operação. Verdadeiro se salvou com sucesso e
     * Falso se não conseguir salvar.
     */
    @Override
    public boolean eliminar(int id, String table)
    {
        result=false;

        try
        {
            sql = "DELETE FROM " + table + " WHERE " + table + ".id = ?";
           
            ps = connection.prepareStatement(sql);

            ps.setInt(1, id);

            result = (ps.executeUpdate()!=0);

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    /**
     * Procura por um registo da base de dados.
     * @param id chave do registo.
     * @param table nome da tabela na base de dados.
     * @return o resultSet com o registo. Ou nulo caso não encontre o registo.
     */
    @Override
    public ResultSet procurarPor(int id, String table)
    {
        try
        {
            sql = "SELECT * FROM " + table + " WHERE " + table + ".id = ?";

            ps = connection.prepareStatement(sql);

            ps.setInt(1, id);

            rs = ps.executeQuery();

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }

        return rs;
    }

    /**
     * Procura por um registo da base de dados pelo campo definido pelo utilizador.
     * @param table nome da tabela na base de dados.
     * @param campo o campo de comparacao.
     * @param valor o valor a ser procurado.
     * @return o resultSet com o registo. Ou nulo caso não encontre o registo.
     */
    @Override
    public ResultSet procurarPorCampo(String table, String campo, String valor)
    {
        try
        {
            sql = "SELECT * FROM " + table + " WHERE " + table + "." + campo + " = '" + valor +"'";

            ps = connection.prepareStatement(sql);

            rs = ps.executeQuery();

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }

        return rs;
    }

    /**
     * Elimina um registo da base de dados pelo campo definido pelo utiliador.
     * @param table nome da tabela na base de dados.
     * @param campo o campo de comparacao.
     * @param valor o valor a ser procurado.
     * @return o resultSet com o registo. Ou nulo caso não encontre o registo.
     */
    @Override
    public boolean eliminarPorCampo(String table, String campo, String valor)
    {
        try
        {
            sql = "DELETE FROM " + table + " WHERE " + table + "." + campo + " = '" + valor +"'";

            ps = connection.prepareStatement(sql);

            result = (ps.executeUpdate()!=0);

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }

        return result;
    }


    /**
     * Procura por todos os registos tabela na base de dados.
     * @param table nome da tabela na base de dados.
     * @return o resultSet com o registo. Ou nulo caso não encontre o registo.
     */
    @Override
    public ResultSet procurarTodos(String table, String orderField)
    {
        try
        {
            sql = "SELECT * FROM " + table + " ORDER BY " + orderField;

            ps = connection.prepareStatement(sql);

            rs = ps.executeQuery();

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return rs;
    }

    /**
     * Procura por todos os registos tabela na base de dados com semelhanças no critério de selecção.
     * @param table nome da tabela na base de dados.
     * @return o resultSet com o registo. Ou nulo caso não encontre o registo.
     */
    @Override
    public ResultSet procurarTodosLike(String table, String orderField, String searchField)
    {
        try
        {
            sql = "SELECT * FROM " + table + ""
                    + " WHERE "+ orderField + " LIKE '" + searchField.trim() + "%'";

            ps = connection.prepareStatement(sql);

            rs = ps.executeQuery();

        }
        catch (SQLException ex)
        {
            Logger.getLogger(ControllerGeneric.class.getName()).log(Level.SEVERE, null, ex);
        }

        return rs;
    }
    
    /**
     * Método abstracto que deverá ser definido por cada modelo do projecto para salvar os dados.
     * @param object representa a entidade que deverá ser salva na base de dados.
     * @return o resutado da operação verdadeiro se salvar e falso se não puder salvar.
     */
    @Override
    public abstract boolean save(Object object);

    /**
     * Método abstracto que deverá ser definido por cada modelo do projecto para actualizar os dados.
     * @param object representa a entidade que deverá ser actualizada na base de dados.
     * @return o resutado da operação verdadeiro se actualizar e falso se não puder actualizar.
     */
    @Override
    public abstract boolean update(Object object);
}
